package com.hopkinscsc.windows;

import javax.swing.*;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.*;

/**
 *	Creates a window and throws a new engine into it.
 */
public class Window implements KeyListener{
	/**
	 * 	
	 */
	private static final long serialVersionUID = 1L;

	// define window variables here
	private int WIDTH; private int HEIGHT;
	private JFrame parentWindow;
	Engine mainEngine;

	private Collection<KeyboardListener> keyboardListeners = new ArrayList <KeyboardListener>();
	
	public static int windowCount = 0;
	
	/**
	 *  This constructor creates a window with the given width and height and places it on the screen
	 *  @param   name     the name of the new window, will be displayed at the top of the window. (note: this is not a reference to the window)
	 *  @param   width    the width of the new window in pixels
	 *  @param   height   the height of the new window in pixels
	 *  @see javax.swing
	 */
	public Window (String name, int width, int height){
		// import variables
		this.WIDTH  = width;
		this.HEIGHT = height;
		
		
		// create the window
		parentWindow = new JFrame(name);
		parentWindow.setSize(this.WIDTH, this.HEIGHT);
		parentWindow.getContentPane().add(mainEngine = new Engine());
		parentWindow.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);		
		parentWindow.setVisible(true);
		
		WindowListener windowListener = new WindowAdapter(){
			public void windowClosing (WindowEvent w){
				parentWindow.dispose();
				Window.windowCount--;
				if (Window.windowCount == 0)
					System.exit(0);
			}
		};
		Window.windowCount++;
		parentWindow.addWindowListener(windowListener);
		parentWindow.addKeyListener(this);
	}
	/**
	 * Places a new circle/oval in the window
	 * @param string the words the text will display
	 * @param x      the x position of the new circle (origin is top left corner)
	 * @param y      the y position of the new circle (origin is top left corner)
	 * @return       the text object, which can be manipulated directly
	 * @see Text
	 */
	public Text addText(String string, int x, int y){
		Text text = new Text(string, x, y);
		mainEngine.addElement(text);
		return text;
	}
	/**
	 * Places a new circle/oval in the window
	 * @param dw 	the width diameter of the new circle in pixels
	 * @param dh 	the height diameter of the new circle in pixels
	 * @param x      the x position of the new circle (origin is top left corner)
	 * @param y      the y position of the new circle (origin is top left corner)
	 * @return       the circle object, which can be manipulated directly
	 * @see Circle
	 */
	public Circle addCircle(int dw, int dh, int x, int y){
		Circle circle = new Circle(dw, dh, x, y);
		mainEngine.addElement(circle);
		return circle;
	}
	/**
	 * Places a new rectangle in the window
	 * @param width  the width of the new rectangle in pixels
	 * @param height the height of the new rectangle in pixels
	 * @param x      the x position of the new rectangle (origin is top left corner)
	 * @param y      the y position of the new rectangle (origin is top left corner)
	 * @return       the rectangle object, which ca be manipulated directly
	 * @see Rectangle
	 */
	public Rectangle addRectangle(int width, int height, int x, int y){
		Rectangle rectangle = new Rectangle(x, y, width, height);
		mainEngine.addElement(rectangle);
		return rectangle;
	}
	/**
	 * Places a new icon in the window
	 * @param fileName the file to get the icon from
	 * @param x        the x position of the new icon (origin is top left corner)
	 * @param y        the y position of the new icon (origin is top left corner)
	 * @return         the new icon, which can be manipulated directly
	 * @see Icon
	 */
	public Icon addIcon(String fileName, int x, int y)
	{
		Icon icon = new Icon(fileName, x, y, parentWindow);
		mainEngine.addElement(icon);
		return icon;
	}
	/**
	 * Places a new icon in the window
	 * @param fileName the file to get the icon from
	 * @param x        the x position of the new icon (origin is top left corner)
	 * @param y        the y position of the new icon (origin is top left corner)
	 * @param width    the width the new icon will be resized to
	 * @param height   the height the new icon will be resized to
	 * @return         the new icon, which can be manipulated directly
	 * @see Icon
	 */
	public Icon addIcon(String fileName, int x, int y, int width, int height)
	{
		Icon icon = new Icon(fileName, x, y, width, height, parentWindow);
		mainEngine.addElement(icon);
		return icon;
	}
	/**
	 * Moves the window to a new location
	 * @param x the new x position of the window
	 * @param y the new y position of the window
	 */
	public void move(int x, int y){
		parentWindow.setLocation(x, y);
	}
	/**
	 * Resize the current window
	 * @param width the new width
	 * @param height the new height
	 */
	public void resize(int width, int height){
		this.WIDTH = width; this.HEIGHT = height;
		parentWindow.setSize(width, height);
	}
	/**
	 * Renames the window
	 * @param name the new name of the window
	 */
	public void rename(String name){
		parentWindow.setTitle(name);
	}
	/**
	 * Adds a new Listener to the Window and calls its init method
	 * @param listener The Listener to add to the windows
	 */
	public void addListener(Listener listener) {
		listener.init();
		if (listener instanceof KeyboardListener){
			KeyboardListener keyboardListener = (KeyboardListener) listener;
			keyboardListeners.add(keyboardListener);
		}else if (listener instanceof ClickListener){
			
		}
	}
	@Override
	/**
	 * Gets called when a key is pressed
	 */
	public void keyPressed(KeyEvent e) {
		Iterator iterator = keyboardListeners.iterator();
		KeyboardListener thisListener;
		while (iterator.hasNext()){
			thisListener = (KeyboardListener) iterator.next();
			if (thisListener.key == e.getKeyCode()){
				thisListener.onDown(e);
			}
		}
	}
	@Override
	public void keyReleased(KeyEvent e) {
		Iterator iterator = keyboardListeners.iterator();
		KeyboardListener thisListener;
		while (iterator.hasNext()){
			thisListener = (KeyboardListener) iterator.next();
			if (thisListener.key == e.getKeyCode())
				thisListener.onUp(e);
		}		
	}
	@Override
	public void keyTyped(KeyEvent e) {
		Iterator iterator = keyboardListeners.iterator();
		KeyboardListener thisListener;
		while (iterator.hasNext()){
			thisListener = (KeyboardListener) iterator.next();
			if (thisListener.key == e.getKeyCode())
				thisListener.onPress(e);
		}		
	}
}
